﻿// Copyright 2009 Mike Geise
// 
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
// 
//     http://www.apache.org/licenses/LICENSE-2.0
// 
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.

namespace Falcon.Core.Controllers
{
	using System.Collections.Generic;
	using System.Web.Mvc;
	using Falcon.Core.ActionResults;
	using Falcon.Core.Domain;
	using Falcon.Core.Domain.Enums;
	using Falcon.Core.Domain.Extensions;
	using Falcon.Core.Domain.Services;
	using Falcon.Core.Domain.Values;
	using Falcon.Core.Extensions;
	using Falcon.Core.Validation;

	[Authorize]
	public class UserMessageController : DefaultController
	{
		public UserMessageController(
			IUserMessageService userMessageService,
			IUserMessageFolderService userMessageFolderService,
			IAttachmentStoreService attachmentStoreService)
		{
			this.UserMessageService = userMessageService;
			this.UserMessageFolderService = userMessageFolderService;
			this.AttachmentStoreService = attachmentStoreService;
		}

		public IUserMessageService UserMessageService
		{
			get; 
			private set;
		}

		public IUserMessageFolderService UserMessageFolderService
		{
			get;
			private set;
		}

		public IAttachmentStoreService AttachmentStoreService
		{
			get;
			private set;
		}

		[AcceptVerbs(HttpVerbs.Get)]
		public ActionResult Index(string folder, int? page)
		{
			var messages = UserMessageService.GetPaged(new UserMessageSpecification
			{
				UserId = Identity.Id, 
				Folder = folder, 
				Page = page,
				Limit = Settings.Users.MessagePageLimit
			});

			var message = messages.FirstOrDefault();

			return message.CanView ? View(Views.Index, messages.ToGrouped()) : NotAuthorized();
		}

		[AcceptVerbs(HttpVerbs.Get)]
		public ActionResult Detail(int id)
		{
			var message = UserMessageService.GetById(id);

			if (message == null)
			{
				return Error(Resources.Messages.UserMessageNotFound);
			}

			UserMessageService.MarkRead(message);

			return message.CanView ? View(Views.Detail, message) : NotAuthorized();
		}

		[AcceptVerbs(HttpVerbs.Get)]
		public ActionResult Create(string mode, int? id, int? uid)
		{
			var value = new UserMessageCreate();

			UserMessage message;

			if (id.HasValue)
			{
				message = UserMessageService.GetById(id.Value);

				if (message == null)
				{
					return Error(Resources.Messages.UserMessageNotFound);
				}

				value.PopulateBasedOnMode(message, mode.AsEnum<UserMessageCreateMode>());
			}
			else
			{
				message = UserMessageService.Create();
			}

			return message.CanCreate ? View(Views.Create, value) : NotAuthorized();
		}

		[AcceptVerbs(HttpVerbs.Post)]
		public ActionResult Create(UserMessageCreate value)
		{
			try
			{
				var message = UserMessageService.Create();

				if (!message.CanCreate)
				{
					return NotAuthorized();
				}

				value.Attachment.Source = Request.Files[0];

				if (AttachmentStoreService.Process(value.Attachments, value.Attachment))
				{
					return View(Views.Create, value);
				}

				UserMessageService.Insert(message, value);

				return RedirectToRoute(Routes.UserMessageIndex);
			}
			catch (ValidationException exception)
			{
				ModelState.CopyValidationExceptions(exception);
			}

			return View(Views.Create, value);
		}

		[AcceptVerbs(HttpVerbs.Post)]
		public ActionResult Update(UserMessageUpdate[] values, UserMessageAction value)
		{
			var actions = new List<UserMessageAction>
			{
				UserMessageAction.MoveToFolder,
				UserMessageAction.ExportCsv,
				UserMessageAction.ExportXml,
				UserMessageAction.ExportText
			};

			if (actions.Contains(value))
			{
				IList<UserMessage> messages = new List<UserMessage>();

				for (var i = 0; i < values.Length; i++)
				{
					if (values[i].Selected == false)
					{
						continue;
					}

					var message = UserMessageService.GetById(values[i].Id);

					if (message != null && message.CanUpdate)
					{
						messages.Add(message);
					}
				}

				if (value == UserMessageAction.MoveToFolder)
				{
					return View(Views.Move, messages);
				}

				return new UserMessageDownloadResult(Identity.Id, messages, value);
			}

			UserMessageService.Update(values, value);

			return RedirectToRoute(Routes.UserMessageIndex);
		}

		[AcceptVerbs(HttpVerbs.Post)]
		public ActionResult Move(int id, UserMessageMove[] values)
		{
			var folder = UserMessageFolderService.GetById(id);

			UserMessageService.Move(values, folder);

			return RedirectToRoute(Routes.UserMessageIndex, new { folder = folder.Slug });
		}
	}
}